#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cmath>
#include <ctime>
#include <algorithm>
#include <cstring>
#include <vector>
#include <set>
#include <map>
#include <bitset>
#include <queue>
#include <complex>
#include <cassert>
 
using namespace std;

const long long hx = (long long)2e5 + 3;
const int x[16] = {0, 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3};
const int y[16] = {0, 0, 1, 2, 3, 0, 1, 2, 3, 0, 1, 2, 3, 0, 1, 2};
const int dx[4] = {-1, 0, 1, 0};
const int dy[4] = {0, -1, 0, 1};

struct answer {
	short ans;
	char a[4][4];
};

map <long long, answer> d;
map <long long, short> h;

bool good(int x, int y) {
	return x >= 0 && x < 4 && y >= 0 && y < 4;
}

long long get_hash(answer &cur) {
	long long res = 0;
	for (int i = 0; i < 4; i++) {
		for (int j = 0; j < 4; j++) {
			res = res * hx + cur.a[i][j] + 1;
		}
	}
	return res;
}

short get_h(answer &cur) {
	short res = 0;
	for (int i = 0; i < 4; i++) {
		for (int j = 0; j < 4; j++) {
			if (cur.a[i][j] == 0) {
				continue;
			}
			res += abs(i - x[cur.a[i][j]]) + abs(j - y[cur.a[i][j]]);
		}
	}
	return res;
}

bool good_state(answer &cur) {
	int num = 1;
	for (int i = 0; i < 4; i++) {
		for (int j = 0; j < 4; j++) {
			if (i == 3 && j == 3){
				continue;
			}
			if (cur.a[i][j] != num) {
				return false;
			}
			num++;
		}
	}
	return true;
}

int main() {
	freopen("input.txt", "r", stdin);
	freopen("output.txt", "w", stdout);
	answer cur;
	for (int i = 0; i < 4; i++) {
		for (int j = 0; j < 4; j++) {
			scanf("%d", &cur.a[i][j]);
		}
	}
	cur.ans = 0;
	set <pair <short, long long> > s;
	long long hash = get_hash(cur);
	d[hash] = cur;
	h[hash] = get_h(cur);
	s.insert(make_pair(d[hash].ans + h[hash], hash));
	while (!s.empty()) {
		hash = s.begin()->second;
		s.erase(s.begin());
		cur = d[hash];
		if (good_state(cur)) {
			printf("%d\n", (int)cur.ans);
			return 0;
		}
		for (int i = 0; i < 4; i++) {
			for (int j = 0; j < 4; j++) {
				if (cur.a[i][j] == 0) {
					for (int z = 0; z < 4; z++) {
						if (good(i + dx[z], j + dy[z])) {
							swap(cur.a[i][j], cur.a[i + dx[z]][j + dy[z]]);
							cur.ans++;
							hash = get_hash(cur);
							if (d.find(hash) == d.end()) {
								d[hash] = cur;
								h[hash] = get_h(cur);
								s.insert(make_pair(cur.ans + h[hash], hash));
							}
							else {
								if (d[hash].ans > cur.ans) { 
									s.erase(make_pair(d[hash].ans + h[hash], hash));
									d[hash] = cur;
									s.insert(make_pair(d[hash].ans + h[hash], hash));
								}
							}
							cur.ans--;
							swap(cur.a[i][j], cur.a[i + dx[z]][j + dy[z]]);
						}
					}
				}
			}
		}
	}
	printf("-1\n");
	return 0;
}
